//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifdef __cplusplus
extern "C" {
#endif

#include "flstatus.h"
#include "flreq.h"
#include "flsocket.h"
#include "fatfilt.h"
#include "flioctl.h"
#include "blockdev.h"
#include "docbdk.h"
#include "config.h"
int __cdecl cprintf(const char *format, ...);
static unsigned long  memAddr = RAM_START;
static IOreq ioreqPar;

IOreq* IoreqPar (FLHandle irHandle,unsigned int irFlags,void *irData,long irLength,long irCount)
{
	ioreqPar.irHandle=(irHandle<<4)+0;
	ioreqPar.irFlags=irFlags;
	ioreqPar.irData=irData;
	ioreqPar.irLength=irLength;
	ioreqPar.irCount=irCount;
	return &ioreqPar;
}

int docInit()
{
	bdkInit();
	return 0;
}


int IdentifyDoc (void)
{
        IOreq   ioreq;
        PhysicalInfo    info;

	FLStatus status;
        status = flInit();
        if( noOfSockets == 0 )
                return 0;

        ioreq.irHandle = 0;
        ioreq.irData = &info;
        if( flGetPhysicalInfo ( &ioreq ) != flOK )
                return 0;

        cprintf("DOC size 0x%lx\n", info.mediaSize);
        cprintf("DOC unit size 0x%lx\n", info.unitSize);
        cprintf("DOC type 0x%d\n\n", info.mediaType );

        return 1;
}


int GetBinaryPartitionInfo()
{
	BDKStruct BDKStructRec;
	FLStatus  status;

    memset(&BDKStructRec, 0, sizeof(BDKStruct));

	memcpy(BDKStructRec.oldSign, "BOOT", 4);
	memcpy(BDKStructRec.newSign, "BDKP", 4);

	status = bdkPartitionInfo(IoreqPar(0, 0, &BDKStructRec, 0, 0));
	if(status == flOK)
	{
		cprintf("GetBinaryPartitionInfo-----ok!\n");
		cprintf("BinaryPartition0 length = %d\n", ioreqPar.irLength / 1024);
		cprintf("sub Partition0 length = %d\n", BDKStructRec.length / 1024);
		cprintf("sub Partition0 startblock = %d\n", BDKStructRec.startingBlock);
		cprintf("Number of binary partitions = %d\n", BDKStructRec.flags);
	}
	else
		cprintf("GetBinaryPartitionInfo-----failed! return %x\n", status);

	memset(&BDKStructRec, 0, sizeof(BDKStruct));

	memcpy(BDKStructRec.oldSign, "BDKP", 4);
	memcpy(BDKStructRec.newSign, "BOOT", 4);

	status = bdkPartitionInfo(IoreqPar(1, 0, &BDKStructRec, 0, 0));
	if(status == flOK)
	{
		cprintf("GetBinaryPartitionInfo-----ok!\n");
		cprintf("BinaryPartition0 length = %d\n", ioreqPar.irLength / 1024);
		cprintf("sub Partition0 length = %d\n", BDKStructRec.length / 1024);
		cprintf("sub Partition0 startblock = %d\n", BDKStructRec.startingBlock);
		cprintf("Number of binary partitions = %d\n", BDKStructRec.flags);
	}
	else
		cprintf("GetBinaryPartitionInfo-----failed! return %x\n", status);

    return 0;
}

int CreateBinarySubpartition(int subPartitionNo, int length, char sign[4])
{
	BDKStruct BDKStructRec;
	FLStatus  status;

	BDKStructRec.startingBlock = 0;
	BDKStructRec.length = length;
	BDKStructRec.signOffset=8;

	memcpy (BDKStructRec.oldSign, "KERN", 4);
	memcpy (BDKStructRec.newSign, sign, 4);
	/* memcpy (BDKStructRec.newSign, "LOGO", 4); */

	/* memcpy(BDKStructRec.oldSign, "BIPO", 4); */
	/* memcpy(BDKStructRec.newSign, "LOGO", 4); */

	status = bdkCreate(IoreqPar(subPartitionNo,0, &BDKStructRec, 0, 0));

  	BDKStructRec.signOffset=8;
	BDKStructRec.startingBlock=0;
	memcpy (BDKStructRec.oldSign, sign, 4);
	status = bdkPartitionInfo (IoreqPar(1,0,&BDKStructRec,0,0) );
	cprintf ( "number of sub-partition = 0x%x\r\n", BDKStructRec.flags );
	cprintf ( "size of sub-partition = %ld = %dK\r\n", BDKStructRec.startingBlock, BDKStructRec.startingBlock/1024 );

	if(status == flOK)
		return 1;

	cprintf("CreateBinarySubpartition----failed---status = %d\n", status);

	return 0;

/* 	bdkStruct.length=(clParams.subPart[b].dwSize%physicalInfo.unitSize)?clParams.subPart[b].dwSize/physicalInfo.unitSize+1:clParams.subPart[b].dwSize/physicalInfo.unitSize; */

/* 	memcpy(bdkStruct.oldSign,clParams.binaryFp[b>>3].sign,BINARY_SIGNATURE_NAME); */
/* ExMemCpy (bdkStruct.newSign,clParams.subPart[b].sign,BINARY_SIGNATURE_NAME); */
/* bdkStruct.signOffset=8;  */
/* bdkStruct.startingBlock=0; */
/* CheckStat (bdkCreate (SetIoreq ((b>>3)<<4,0,&bdkStruct,0,0)),FL_BINARY_CREATE); */
/* 	} */
/* 	return EX_OK; */
}


int FormatDoc()
{
	FormatParams2 fp = STD_FORMAT_PARAMS2;
  	BDTLPartitionFormatParams bdtlP[] = { STD_BDTL_PARAMS, STD_BDTL_PARAMS, STD_BDTL_PARAMS, STD_BDTL_PARAMS };
  	BinaryPartitionFormatParams bdkP[] = { STD_BINARY_PARAMS, STD_BINARY_PARAMS,STD_BINARY_PARAMS };
  	IOreq ioreq;
  	FLStatus status;

  	ioreqPar.irHandle = 0;  //initial value is 0
	/* BDTL info */
  	fp.noOfBDTLPartitions = BDTL_NUMBER;
  	bdtlP[0].length = BDTL0_LENGTH;
  	bdtlP[0].flags = TL_NORMAL_FORMAT;
	bdtlP[1].length = BDTL1_LENGTH;
	bdtlP[1].flags = TL_NORMAL_FORMAT;
#ifdef DOC_SIZE_128M
  	bdtlP[2].length = BDTL2_LENGTH;
  	bdtlP[2].flags = TL_NORMAL_FORMAT;
	bdtlP[3].length = BDTL3_LENGTH;
	bdtlP[3].flags = TL_NORMAL_FORMAT;
#endif

  	fp.BDTLPartitionInfo = bdtlP;
  	/* ioreq.irFlags = TL_FORMAT_FAT; */
	ioreq.irFlags = TL_NORMAL_FORMAT;

  	/* BDK info */
  	/* fp.noOfBinaryPartitions = BDK_NUMBER; */
  	/* bdkP[0].length = BDK0_LENGTH; */
	/* bdkP[0].flags  = TL_SPL_FORMAT; */
  	/* bdkP[1].length = BDK1_LENGTH; */

	fp.noOfBinaryPartitions = 2;
	bdkP[0].length = 1*1024*1024;
	bdkP[0].flags  = TL_SPL_FORMAT;
	memcpy(bdkP[0].sign, "BOOT", 4);
	bdkP[1].length = 2*1024*1024;
	memcpy(bdkP[1].sign, "BDKP", 4);           // new name for BDK1



  	fp.binaryPartitionInfo = bdkP;

  	status = flFormatPhysicalDrive( IoreqPar(0,0,&fp,0,0) );
  	if( status != flOK )
  	{
		return 0;
  	}
  	else
  	{
		CreateBinarySubpartition(1, 4, "LOGO");
		CreateBinarySubpartition(1, 4, "TATA");
		CreateBinarySubpartition(1, 4, "TATB");
	  	return 1;
  	}
}

int ReadIPL(unsigned char * ptr)
{
    FLStatus status;

	status = flReadIPL(IoreqPar(0,FL_IPL_MODE_NORMAL,ptr,2*1024,0) );
  	if( status != flOK )
	{
		return 0;
	}
  	else return 1;
}

int WriteIPL(unsigned char * ptr)
{
	FLStatus status;

	status = flWriteIPL(IoreqPar(0,FL_IPL_MODE_NORMAL,ptr,2*1024,0) );
  	if( status != flOK )
	{
		return 0;
	}
  	else return 1;
}

int InitWriteSPL(unsigned int PartitionSize)
{
    BDKStruct BDKStructRec;
    FLStatus status;

	memcpy(BDKStructRec.oldSign, "BOOT", 4);
    memcpy(BDKStructRec.newSign, "BOOT", 4);
	BDKStructRec.startingBlock = 0;
    BDKStructRec.signOffset = 8;
	BDKStructRec.length = PartitionSize;
	BDKStructRec.flags = BDK_COMPLETE_IMAGE_UPDATE;

	status = bdkWriteInit(IoreqPar(0,0,&BDKStructRec,0,0) );
	if( status!= flOK )
    {
        return 0;
    }
    else return 1;
}

int WriteSPL(unsigned char * ptr,int size)
{

    BDKStruct BDKStructRec;
    FLStatus status;
    memcpy(BDKStructRec.oldSign, "BOOT", 4);
    memcpy(BDKStructRec.newSign, "BOOT", 4);
	BDKStructRec.startingBlock = 0;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = size;

    status = bdkWriteBlock(IoreqPar(0, 0, &BDKStructRec, 0, 0) );
    if( status!=flOK )
	{
        return 0;
	}
	else
	{
	    return 1;
	}
}

int InitReadSPL(unsigned int PartitionSize)
{
    BDKStruct BDKStructRec;
        FLStatus status;
	memcpy(BDKStructRec.oldSign, "BOOT", 4);
        memcpy(BDKStructRec.newSign, "BOOT", 4);
	BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
	BDKStructRec.length = PartitionSize;
	BDKStructRec.flags = BDK_COMPLETE_IMAGE_UPDATE;

	status = bdkReadInit(IoreqPar(0,0,&BDKStructRec,0,0) );
	if( status!= flOK )
    {
        return 0;
    }
    else return 1;
}

int ReadSPL(unsigned char * ptr,int size)
{
    BDKStruct BDKStructRec;
        FLStatus status;
    memcpy(BDKStructRec.oldSign, "BOOT", 4);
        memcpy(BDKStructRec.newSign, "BOOT", 4);
	BDKStructRec.startingBlock = 0;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = size;
    status = bdkReadBlock(IoreqPar(0, 0, &BDKStructRec, 0, 0) );
    if( status!= flOK )
    {
        return 0;
    }
    else return 1;
}

int WriteLogo (unsigned char * ptr,int size)
{
	BDKStruct BDKStructRec;
    FLStatus status;
	memcpy (BDKStructRec.oldSign, "BOOT", 4);
	memcpy(BDKStructRec.newSign, "BOOT", 4);
	BDKStructRec.startingBlock = 20;
	BDKStructRec.signOffset = 8;
	BDKStructRec.length = 240*320*2;
    //cprintf("size is %d\n",size);
	status = bdkWriteInit(IoreqPar (0,0,&BDKStructRec,0,0) );
	if( status!= flOK )
    {
        return 0;
    }

	BDKStructRec.startingBlock = 20;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = 240*320*2;

	status = bdkWriteBlock (IoreqPar (0x0, 0, &BDKStructRec, 0, 0) );
    if( status!=flOK )
	{
	    cprintf("write logo wrong\n");
		return 0;
	}
	else
	{
		return 1;
	}
}

int MySave(char * name, unsigned char * buf, int len);

int ReadLogo (unsigned char * ptr,int size)
{
	BDKStruct BDKStructRec;
    FLStatus status;
    memcpy( BDKStructRec.oldSign, "BOOT", 4 );
    memcpy(BDKStructRec.newSign, "BOOT", 4);
    BDKStructRec.startingBlock = 20;
    BDKStructRec.signOffset = 8;
    BDKStructRec.length = 240*320*2;
    status = bdkReadInit ( IoreqPar (0x0,0,&BDKStructRec,0,0) );
    if( status!= flOK )
    {
         cprintf ("ReadLogo-----bdkReadInit----------failed\n");
         return 0;
    }
    cprintf("size is %d\n",size);
    BDKStructRec.startingBlock = 20;
    BDKStructRec.bdkBuffer = ptr;
    BDKStructRec.length = 240*320*2;

    status = bdkReadBlock ( IoreqPar (0x0, 0, &BDKStructRec, 0, 0) );
    if( status!=flOK )
    {
         cprintf ("ReadLogo-----bdkReadBlock----------failed\n");
         return 0;
    }

    return 1;
}

int WriteTatTable(unsigned char *buff)
{
	BDKStruct BDKStructRec;
        FLStatus status;
        unsigned char * ptr=(unsigned char*)buff;

        memcpy (BDKStructRec.oldSign, "TATT", 4);
        BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
        BDKStructRec.length = 256*1024;

        status = bdkWriteInit(IoreqPar (0x01,0,&BDKStructRec,0,0) );
                if( status!= flOK )
        {
                return 0;
        }

        BDKStructRec.startingBlock = 0;
        BDKStructRec.bdkBuffer = ptr;
        BDKStructRec.length = 256*1024;

        status = bdkWriteBlock (IoreqPar (0x01, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
        {
		cprintf("WriteTatTable Error\n");
                return 0;
        }
        else
        {
                return 1;
        }
}

int WriteTAT()
{
	BDKStruct BDKStructRec;
        FLStatus status;
        unsigned char * ptr=(unsigned char*)memAddr;

	memcpy (BDKStructRec.oldSign, "TATT", 4);
	BDKStructRec.startingBlock = 0;
	BDKStructRec.signOffset = 8;
	BDKStructRec.length = 256*1024;

	status = bdkWriteInit(IoreqPar (0x01,0,&BDKStructRec,0,0) );
		if( status!= flOK )
        {
                return 0;
        }

	BDKStructRec.startingBlock = 0;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = 256*1024;

	status = bdkWriteBlock (IoreqPar (0x01, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

int ReadTatTable(unsigned char *buff)
{
	BDKStruct BDKStructRec;
        FLStatus status;


        memcpy( BDKStructRec.oldSign, "TATT", 4 );
        BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
        BDKStructRec.length = 256*1024;
        status = bdkReadInit ( IoreqPar (0x1,0,&BDKStructRec,0,0) );
        if( status!= flOK )
        {
                cprintf ("ReadTAT-----bdkReadInit----------failed\n");
                return 0;
        }

        BDKStructRec.startingBlock = 0;
        BDKStructRec.bdkBuffer = buff;
        BDKStructRec.length = 256*1024;

        status = bdkReadBlock ( IoreqPar (0x1, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
        {
                cprintf ("ReadTAT-----bdkReadBlock----------failed\n");
                return 0;
        }


        int i = 0, j = 0;
        for(i = 0; i < 400; i++)
        {
                for(j = 0; j < 16; j++)
                {
                        cprintf ("%x ", *(buff + i * 16 + j));
                }
                if((i + 1) % 16 == 0)
                        cprintf ("\n                                                              \n");
                cprintf ("\n");
        }

        return 1;

}


int ReadTAT ()
{
	BDKStruct BDKStructRec;
        FLStatus status;

	unsigned char buf[1*1024*1024];

       	memcpy( BDKStructRec.oldSign, "TATT", 4 );
        BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
        BDKStructRec.length = 256*1024;
        status = bdkReadInit ( IoreqPar (0x1,0,&BDKStructRec,0,0) );
        if( status!= flOK )
        {
                cprintf ("ReadTAT-----bdkReadInit----------failed\n");
                return 0;
        }

        BDKStructRec.startingBlock = 0;
        BDKStructRec.bdkBuffer = buf;
        BDKStructRec.length = 256*1024;

        status = bdkReadBlock ( IoreqPar (0x1, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
        {
                cprintf ("ReadTAT-----bdkReadBlock----------failed\n");
                return 0;
        }


	int i = 0, j = 0;
	for(i = 0; i < 400; i++)
	{
		for(j = 0; j < 16; j++)
		{
			cprintf ("%x ", *(buf + i * 16 + j));
		}
		if((i + 1) % 16 == 0)
			cprintf ("\n                                                              \n");
		cprintf ("\n");
	}

        return 1;
}



int WriteKernel()
{
	BDKStruct BDKStructRec;
        FLStatus status;
        unsigned char * ptr=(unsigned char*)memAddr;

	memcpy(BDKStructRec.oldSign, "KERN", 4);
	BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
	BDKStructRec.length = 1*1024*1024;
	BDKStructRec.flags = BDK_COMPLETE_IMAGE_UPDATE;

		status = bdkWriteInit(IoreqPar(0x01,0,&BDKStructRec,0,0) );
		if( status!= flOK )
        {
                cprintf("bdkWriteInit ERROR\n");
		return 0;
        }


	BDKStructRec.startingBlock = 0;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = /* BDK1_LENGTH */1*1024*1024;

	cprintf("WriteKernel begin to write blocks\n");

        status = bdkWriteBlock(IoreqPar(0x01, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
	{
               	return 0;
	}
	else
	{
		return 1;
	}

}



int LoadKernel(unsigned long to)
{
        BDKStruct BDKStructRec;
        FLStatus  status;
        unsigned char* ptr = (unsigned char*)to;

        memcpy(BDKStructRec.oldSign, "KERN", 4);
        BDKStructRec.startingBlock = 0;
        BDKStructRec.signOffset = 8;
        BDKStructRec.length = /* BDK1_LENGTH */1*1024*1024;
        status = bdkReadInit (IoreqPar (1, 0, &BDKStructRec, 0, 0) );
        if(status != flOK)
        {
                cprintf("doc_read_os----bdkReadInit----------failed\n");
                return 1;
        }
        BDKStructRec.startingBlock = 0;
        BDKStructRec.bdkBuffer = ptr;
        BDKStructRec.length = /* BDK1_LENGTH */1*1024*1024;

        status = bdkReadBlock (IoreqPar (1, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
        {
                cprintf("doc_read_os----bdkReadBlock----------failed\n");
                return 1;
        }

	return 0;
}

int InitReadBinaryPart(unsigned int PartitionSize)
{
	BDKStruct BDKStructRec;
    FLStatus  status;

    memcpy(BDKStructRec.oldSign, "BDKP", 4);
    BDKStructRec.startingBlock = 0;
    BDKStructRec.signOffset = 8;
    BDKStructRec.length = PartitionSize;
    status = bdkReadInit (IoreqPar (1, 0, &BDKStructRec, 0, 0) );
    if(status != flOK) {
    	cprintf("doc_read_os----bdkReadInit----------failed\n");
    	return 1;
    }
	return 0;
}

int ReadBinaryPart(unsigned long to, unsigned int bufSize)
{
	BDKStruct BDKStructRec;
    FLStatus  status;
	unsigned char* ptr = (unsigned char*)to;

	BDKStructRec.startingBlock = 0;
    BDKStructRec.bdkBuffer = ptr;
    BDKStructRec.length = bufSize;

    status = bdkReadBlock (IoreqPar (1, 0, &BDKStructRec, 0, 0) );
    if( status!=flOK )
    {
    	cprintf("doc_read_os----bdkReadBlock----------failed\n");
    	return 1;
    }

	return 0;
}

int InitWriteBinaryPart(unsigned int PartitionSize)
{
	BDKStruct BDKStructRec;
    FLStatus status;

	memcpy(BDKStructRec.oldSign, "BDKP", 4);
	BDKStructRec.startingBlock = 0;
    BDKStructRec.signOffset = 8;
	BDKStructRec.length = PartitionSize;
	BDKStructRec.flags = BDK_COMPLETE_IMAGE_UPDATE;

	status = bdkWriteInit(IoreqPar(0x01,0,&BDKStructRec,0,0) );
	if( status!= flOK ) {
        cprintf("bdkWriteInit ERROR\n");
		return 1;
    }
	return 0;
}

int WriteBinaryPart(unsigned long from, unsigned int bufSize)
{
	BDKStruct BDKStructRec;
    FLStatus status;
    unsigned char * ptr=(unsigned char*)from;

	BDKStructRec.startingBlock = 0;
	BDKStructRec.bdkBuffer = ptr;
	BDKStructRec.length = bufSize;

	cprintf("WriteBinarayPart begin to write blocks\n");
    status = bdkWriteBlock(IoreqPar(0x01, 0, &BDKStructRec, 0, 0) );
    if( status!=flOK ) {
    	cprintf("WriteBinarayPart ERROR\n");
    	return 1;
	}
	return 0;
}

int doc_BDTL_mount(unsigned int partition)
{
	IOreq ioreq;
	FLStatus stat;

	ioreq.irHandle=(partition << 4) + 0;
	stat=flAbsMountVolume(&ioreq);
	if(stat==flOK)
		return 1;
	else
	{
		cprintf("doc_BDTL_mount->flAbsMountVolume error %d\n",stat);
		return 0;
	}
}

int doc_BDTL_dismount(unsigned int partition)
{
	IOreq ioreq;
	FLStatus stat;

	ioreq.irHandle=(partition << 4) + 0;
	stat=flDismountVolume(&ioreq);
	if(stat!=flOK)
	{
		cprintf("doc_BDTL_dismount->flDismountVolume error %d\n",stat);
		return 0;
	}
	else
		return 1;
}


int doc_info(void)
{

	GetBinaryPartitionInfo();

    	IOreq    ioreq;
	FLStatus status;
	doc_BDTL_mount(0);
	ioreq.irHandle = 0x0;
        status = flSectorsInVolume(&ioreq);
	if(status == flOK)
	  cprintf("BDTL0-----sectors = 0x%x\n", ioreq.irLength);

	doc_BDTL_dismount(0);

	doc_BDTL_mount(1);
	ioreq.irHandle = 0x10;
        status = flSectorsInVolume(&ioreq);
        if(status == flOK)
          cprintf("BDTL1-----sectors = 0x%x\n", ioreq.irLength);
	doc_BDTL_dismount(1);

	return 0;
}

int Get_BDTL_Partition_Size(unsigned int ParNo)
{
	IOreq    ioreq;
	FLStatus status;

	ioreq.irHandle = (ParNo << 4) & 0xf0;
	status = flSectorsInVolume(&ioreq);
	if(status == flOK)
		return ioreq.irLength;
	else
	{
		cprintf("Get_BDTL_Partiton_Size----error---%d\n", status);
		return status;
	}
}

int Get_BDTL_BootSector_NO(unsigned int ParNo)
{
	IOreq    ioreq;
	FLStatus status;

	ioreq.irHandle = (ParNo << 4) & 0xf0;
	status = flBootSectorInVolume(&ioreq);
	if(status == flOK)
		return ioreq.irLength;
	else
	{
		cprintf("Get_BDTL_BootSector_NO----error---%d\n", status);
		return status;
	}
}

int ShowLast512Byte()
{
	unsigned char *to = (unsigned char*)0xa3c2f800;

	int i = 0, j = 0;
	for(i = 0; i < 300; i++)
	{
		for(j = 0; j < 16; j++)
		{
			cprintf ("%x ", *(to + i * 16 + j));
		}
		if((i + 1) % 16 == 0)
			cprintf ("\n                                                              \n");
		cprintf ("\n");
	}
	return 1;
}


int bdkInited = 0;

int doc_oneblock_write(unsigned int partition, unsigned char *buf, unsigned int block)
{
        BDKStruct BDKStructRec;
        FLStatus status;
        unsigned char * ptr=(unsigned char*)buf;

	if(!bdkInited)
	{
		if(partition == 0)
			BDKStructRec.length = BDK0_LENGTH;
		if(partition == 1)
			BDKStructRec.length = BDK1_LENGTH;

		memcpy( BDKStructRec.oldSign, "BIPO", 4 );
        	BDKStructRec.startingBlock = 0;
        	BDKStructRec.signOffset = 8;
        	status = bdkWriteInit( IoreqPar(partition,0,&BDKStructRec,0,0) );
        	if( status!= flOK )
        	{
                	cprintf("bdkWriteInit----------failed\n");
                	return 0;
        	}
		bdkInited = 1;
	}
        BDKStructRec.startingBlock = block;
        BDKStructRec.bdkBuffer = ptr;
        BDKStructRec.length = DOC_BLOCK_SIZE;

        status = bdkWriteBlock( IoreqPar(partition, 0, &BDKStructRec, 0, 0) );
        if( status!=flOK )
        {
                cprintf("bdkWriteBlock----------failed\n");
                return 0;
        }

        return 1;
}

int doc_oneblock_BDTL_write(unsigned int partition, unsigned char *buf, unsigned int block)
{
	IOreq ioreq;
	FLStatus stat;

	ioreq.irHandle=(partition << 4) + 0;
	ioreq.irData=buf;
	ioreq.irSectorNo=block*DOC_PAGES_IN_BLOCK;
	ioreq.irSectorCount=DOC_PAGES_IN_BLOCK;
//Bill
	cprintf("DOC: block=%d\n", block);
	stat=flAbsWrite(&ioreq);
	if(stat==flOK)
		return 1;
	else
	{
		cprintf("doc_oneblock_BDTL_write->flAbsWrite error %d",stat);
		return 0;
	}
}


int WriteRootFs()
{
	cprintf("WriteRootFs---111111\n");
	IOreq ioreq;
	FLStatus stat;

	unsigned char * ptr=(unsigned char*)memAddr;

	doc_BDTL_mount(0x0);
	cprintf ("WriteRootFs---222222\n");

	ioreq.irHandle=(0x0 << 4) + 0;
	ioreq.irData=ptr;
	ioreq.irSectorNo=0;
	cprintf ("WriteRootFs---3333333\n");
	ioreq.irSectorCount=Get_BDTL_Partition_Size(0);
	cprintf ("WriteRootFs------Partition Size = 0x%x\n", ioreq.irSectorCount);
	stat=flAbsWrite(&ioreq);
	doc_BDTL_dismount(0x0);
	if(stat==flOK)
		return 1;
	else
	{
		cprintf("WriteRootFs->flAbsWrite error %d",stat);
		return 0;
	}

}

int WriteMMI()
{
	IOreq ioreq;
	FLStatus stat;

	unsigned char * ptr=(unsigned char*)memAddr;

	cprintf("WriteMMI---1111111111111\n");
	doc_BDTL_mount(0x1);
	cprintf ("WriteMMI---222222222222\n");

	ioreq.irHandle=(0x1 << 4) & 0xf0;
	ioreq.irData=ptr;
	ioreq.irSectorNo=0;
	ioreq.irSectorCount=Get_BDTL_Partition_Size(1);
	cprintf("WriteMMI------Partition Size = 0x%x\n", ioreq.irSectorCount);

	stat=flAbsWrite(&ioreq);
	cprintf ("WriteMMI---3333333333333333\n");
	doc_BDTL_dismount(0x1);
	cprintf ("WriteMMI---4444444444444444\n");
	if(stat==flOK)
		return 1;
	else
	{
		cprintf("WriteMMI->flAbsWrite error %d",stat);
		return 0;
	}
}



int doc_read_rootfs ()
{

        IOreq    ioreq;
        FLStatus stat;

        unsigned char buf[DOC_BLOCK_SIZE * 2];
        memset (buf, 0, DOC_BLOCK_SIZE * 2);

        ioreq.irHandle=0;
        ioreq.irData=buf;
        ioreq.irSectorNo=0;
        ioreq.irSectorCount=4;

        cprintf ("partition size ==%d\r\n",sizeof(PartitionTable));

	doc_BDTL_mount(0);
        stat=flAbsRead(&ioreq);
	doc_BDTL_dismount(0);

        if(stat==flOK)
        {
                int i = 0, j = 0;
                for(i = 0; i < 400; i++)
                {
                        for(j = 0; j < 16; j++)
                        {
                                cprintf ("%x ", *(buf + i * 16 + j));
                        }
                        if((i + 1) % 16 == 0)
                                cprintf ("\n                                                              \n");
                        cprintf ("\n");
                }
                return 1;
        }
        else
        {
                cprintf ("doc_read_rootfs error %d",stat);
                return 0;
        }
}

///////////////////////////////////////////////////////////
int doc_read(int part, unsigned char *buffer, unsigned long sector, int nblocks)
{
    IOreq    ioreq;
    FLStatus stat;
    ioreq.irHandle=(part << 4) + 0;
    ioreq.irData=buffer;
    ioreq.irSectorNo=sector;
    ioreq.irSectorCount=nblocks;
    stat=flAbsRead(&ioreq);
//    assert(stat == flOK);
	if(stat != flOK) return 1;
    return 0;
}

//#define DOC_READONLY

int doc_write(int part, unsigned char *buffer, unsigned long sector, int nblocks)
{
#if !defined(DOC_READONLY)
    IOreq    ioreq;
    FLStatus stat;
    ioreq.irHandle=(part << 4) + 0;
    ioreq.irData=buffer;
    ioreq.irSectorNo=sector;
    ioreq.irSectorCount=nblocks;
    stat=flAbsWrite(&ioreq);
//    assert(stat == flOK);
	if(stat != flOK) return 1;
#endif
    return 0;
}

int doc_delete(int part, unsigned long sector, int nblocks)
{
#if !defined(DOC_READONLY)
    IOreq    ioreq;
    FLStatus stat;
    ioreq.irHandle=(part << 4) + 0;
    ioreq.irSectorNo=sector;
    ioreq.irSectorCount=nblocks;
    stat=flAbsDelete(&ioreq);
    assert(stat == flOK);
#endif
    return 0;
}

int doc_dformat(int part)
{
#if !defined(DOC_READONLY)

#if 1
    IdentifyDoc();
    doc_info();
#endif

  	BDTLPartitionFormatParams bdtlP = STD_BDTL_PARAMS;
  	//IOreq ioreq;
  	FLStatus status;

  	//ioreqPar.irHandle = (part << 4) + 0;
	/* BDTL info */
  	//bdtlP.length = BDTL0_LENGTH;
  	//bdtlP.flags = TL_NORMAL_FORMAT;
    printf("DFormat Logical Driver %d\n", part);
  	status = flFormatLogicalDrive( IoreqPar(part,0,&bdtlP,0,0) );
#endif
  	return 0;
}

int doc_mount(int part)
{
    int ret;
    ret = doc_BDTL_mount(part);
    assert(ret == 1);
    return 0;
}

int doc_unmount(int part)
{
    int ret;
    ret = doc_BDTL_dismount(part);
    //assert(ret == 1);
    return 0;
}

unsigned int doc_getsize(int part)
{
    unsigned int secs = Get_BDTL_Partition_Size(part);
    assert(secs > 1024);
    printf("Get BDTL%d Partion Size %d(M)\n", part, secs>>11);
    return secs*512/*SEC_SIZ*/;
}

unsigned int doc_getcapacity()
{
#ifdef DOC_SIZE_128M
    return SIZE_128M;
#else
    return SIZE_64M;
#endif
}

unsigned int doc_getbootsec(int part)
{
    unsigned int secs = Get_BDTL_BootSector_NO(part);
    printf("Get BDTL%d BootSector Address. %d\n", part, secs<<9);
    return secs*512/*BootSector Address.*/;
}

#define flGetUniqueID(ioreq) bdCall(FL_UNIQUE_ID,ioreq)
unsigned int doc_getuid(unsigned char * buffer)
{
    return flGetUniqueID(IoreqPar (0x0, 0, buffer, 0, 0));
}

#define flDeepPowerDownMode(ioreq) bdCall(FL_DEEP_POWER_DOWN_MODE,ioreq)

void doc_powerdown()
{
    //cprintf("sleep\n");
    flDeepPowerDownMode(IoreqPar (0x0, DEEP_POWER_DOWN, NULL, 0, 0));
}

void doc_resume()
{
    //cprintf("awake\n");
    flDeepPowerDownMode(IoreqPar (0x0, EXIT_DEEP_POWER_DOWN, NULL, 0, 0));
}

#ifdef __cplusplus
}
#endif
